﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using CsvHelper;
using CsvHelper.Expressions;
using CsvHelper.Configuration;
using System.Globalization;
using FireBillBook.Core.Models;
using Microsoft.AspNetCore.Http;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using FireBillBook.Core.Models.QueryContexts;
using FireBillBook.Core.Repos.Interfaces;
using Microsoft.Extensions.Logging;

namespace FireBillBook.Core.Services
{
    public class ImportService : IImportService
    {
        private IServiceProvider _services;

        public ImportService(IServiceProvider services)
        {
            _services = services;
        }

        public string TryGetUploadFolderPath(string platform)
        {
            var directoty = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Uploads", platform.ToString());
            if (!Directory.Exists(directoty))
            {
                Directory.CreateDirectory(directoty);
            }

            return directoty;
        }

        public Task Import(string platform, string filepath)
        {
            if (!File.Exists(filepath))
            {
                throw new FileNotFoundException("Cannot find file.", filepath);
            }

            using (var reader = new StreamReader(filepath))
            {
                using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                {
                    // 注册ClassMap
                    csv.Context.RegisterClassMap<Models.ImportMaps.AliPaymentRecordMap>();
                    var records = csv.GetRecords<Models.OriginalDatas.AliPaymentOriginalData>();
                    throw new NotImplementedException();
                }
            }
        }

        public async Task<List<Models.OriginalDatas.AliPaymentOriginalData>> GetOriginalDatasOfAliPay(IFormFile file)
        {
            using (var stream = file.OpenReadStream())
            using (var reader = new StreamReader(stream, true))
            using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
            {
                csv.Context.RegisterClassMap<Models.ImportMaps.AliPaymentRecordMap>();

                var records = await csv.GetRecordsAsync<Models.OriginalDatas.AliPaymentOriginalData>().ToListAsync();
                return records;
            }
        }

        public Task SaveFile(string datasource, Stream filestream)
        {
            throw new NotImplementedException();
        }

        public async Task<string> SaveFile(UploadPaymentModel model, IFormFile file)
        {
            var saveFolderPath = TryGetUploadFolderPath(model.Platform);
            var saveFilePath = Path.Combine(saveFolderPath, $"{(new Guid()).ToString("N")}{Path.GetExtension(file.FileName)}");
            using (var fileStream = new FileStream(saveFilePath, FileMode.Create, FileAccess.Write))
            {
                await file.CopyToAsync(fileStream);
            }
            return saveFilePath;
        }

        public string TryGetUploadPath()
        {
            throw new NotImplementedException();
        }

        public async Task Import(string platform, IFormFile file)
        {
            var serviceName = (await _services.GetRequiredService<IPlatformStore>().GetByNameAsync(platform)).PlatformServiceKey;

            var platformService = _services
                .GetRequiredService<Services.Interfaces.IPlatformServiceFactory>()
                .GetPlatform(serviceName);

            using var fileStream = file.OpenReadStream();

            var encoding = FileHelper.AutoGuessEncoding(fileStream, _services.GetRequiredService<ILogger<FileHelper>>());

            // 清洗数据
            var cleanedStream = platformService.CleanData(fileStream, encoding);

            using var reader = new StreamReader(cleanedStream);
            using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);

            // 解析数据
            var records = await platformService.ConvertOriginalDatas(csv);

            foreach (var record in records)
            {
                record.DataSourceCode = platform.ToString();
            }

            var repo = _services.GetRequiredService<Repos.Interfaces.IBillingSourceDataRepo>();

            await repo.BulkSaveAsync(records, platform);
        }

        public Task Import(string platform, Stream fileStream)
        {
            throw new NotImplementedException();
        }

        public List<Entities.BillingSourceData> Convert(object originalDatas, string platform)
        {
            var mapper = _services.GetRequiredService<AutoMapper.IMapper>();
            throw new NotImplementedException();

            //switch (platform)
            //{
            //    case PaymentPlatform.AliPay:
            //        return mapper.Map<List<Entities.BillingSourceData>>(originalDatas);
            //        throw new NotImplementedException();
            //    case PaymentPlatform.WechatPay:
            //        throw new NotImplementedException();
            //    default:
            //        throw new NotImplementedException();
            //}

        }

        public async Task<PagingModel<Entities.BillingSourceData>> ListSourceDataAsync(BillingSourceDataListQueryContext queryContext)
        {
            var repo = _services.GetRequiredService<IBillingSourceDataRepo>();
            var data = await repo.ListAsync(queryContext);
            return data;
        }
    }
}
